﻿
#include "Common.h"
#include <iostream>

 //整体控制在最多10%左右的内碎⽚浪费
 //[1,128] 8byte对⻬ freelist[0,16)
 //[128+1,1024] 16byte对⻬ freelist[16,72)
 //[1024+1,8*1024] 128byte对⻬ freelist[72,128)
 //[8*1024+1,64*1024] 1024byte对⻬ freelist[128,184)
 //[64*1024+1,256*1024] 8*1024byte对⻬ freelist[184,208)
static inline size_t _Align(size_t sizeBytes, size_t alignShift)
{
	return (sizeBytes + ((1 << alignShift) - 1)) & (~((1 << alignShift) - 1));
}
static inline size_t _Index(size_t alignBytes, size_t alignShift)
{
	return ((alignBytes + (1 << alignShift) - 1) >> alignShift) - 1;
}
size_t Align(size_t sizeByte)
{
	assert(sizeByte); // 申请大小为0的字节

	int align_shift[] = { 3,4,7,10,13 };

	if (sizeByte <= 128)
		return _Align(sizeByte, align_shift[0]);
	else if (sizeByte <= 1024)
		return _Align(sizeByte, align_shift[1]);
	else if (sizeByte <= 8 * 1024)
		return _Align(sizeByte, align_shift[2]);
	else if (sizeByte <= 64 * 1024)
		return _Align(sizeByte, align_shift[3]);
	else
		return _Align(sizeByte, align_shift[4]);
}
size_t Index(size_t alignByte)
{
	assert(alignByte);

	int align_shift[] = { 3,4,7,10,13 };
	int prev_count[] = { 0,16,72,128,184 };

	if (alignByte <= 128)
		return _Index(alignByte, align_shift[0]) + prev_count[0];
	else if (alignByte <= 1024)
		return _Index(alignByte - 128, align_shift[1]) + prev_count[1];
	else if (alignByte <= 8 * 1024)
		return _Index(alignByte - 1024, align_shift[2]) + prev_count[2];
	else if (alignByte <= 64 * 1024)
		return _Index(alignByte - 8 * 1024, align_shift[3]) + prev_count[3];
	else
		return _Index(alignByte - 64 * 1024, align_shift[4]) + prev_count[4];
}
unsigned BatchNum(size_t alignByte) // 计算获取内存的批量
{
	assert(alignByte);

	// 申请的内存块单位大小与获取的内存批量成反比
	int retCount = MAX_BYTES_COUNT / alignByte;
	// 调下限
	retCount = std::max(MIN_BATCH_COUNT, retCount);
	// 调上限
	retCount = std::min(MAX_BATCH_COUNT, retCount);

	return retCount;
}
unsigned PagesNum(size_t sizeBytes)
{
	assert(sizeBytes);

	return ((sizeBytes + (1 << UNIT_PAGE_SHIFT) - 1) >> UNIT_PAGE_SHIFT);
}
void FreeList::clear()
{
	_freelist = nullptr;
	_size = 0;
}
void FreeList::push_front(void* obj)
{
	assert(obj);

	NextMemoryAddr(obj) = _freelist;
	_freelist = obj;
	++_size;
}
void FreeList::pop_front()
{
	assert(_freelist);

	_freelist = NextMemoryAddr(_freelist);
	--_size;
}
void* FreeList::front() const
{
	assert(_freelist);

	return _freelist;
}
bool FreeList::empty() const
{
	return _size == 0;
}
size_t FreeList::size() const
{
	return _size;
}

bool SpanList::empty()
{
	assert(_head);
	return _head->_next == _head;
}
Span* SpanList::front()
{
	assert(!empty());
	return _head->_next;
}
Span* SpanList::GetNoEmptySpan()
{
	if (empty()) return nullptr;

	auto cur = _head->_next;
	while (cur != _head)
	{
		if (cur->_freelist.empty() == false)
			return cur;
		cur = cur->_next;
	}
	return nullptr;
}
void SpanList::pop_front()
{
	assert(!empty());
	erase(_head->_next);
}
void SpanList::push_front(Span* obj)
{
	auto next = _head->_next;

	obj->_next = next;
	obj->_prev = _head;

	next->_prev = obj;
	_head->_next = obj;
}
void SpanList::erase(Span* obj) // 将span从所属的带头双向循环链表中剥离出来
{
	assert(obj); 
	assert(obj->_prev && obj->_next);

	auto prev = obj->_prev;
	auto next = obj->_next;
	prev->_next = next;
	next->_prev = prev;

	obj->_prev = obj->_next = nullptr;
}
#include <Windows.h>
void* SystemAlloc(size_t kpage)
{
#ifdef _WIN32 // windows系统
	void* ptr = VirtualAlloc(0, kpage << UNIT_PAGE_SHIFT, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
#elif __linux__ // linux系统
#endif
	if (ptr == nullptr) throw std::bad_alloc();
	return ptr;
}
void SystemFree(void* ptr)
{
	if (ptr == nullptr) return;
#ifdef _WIN32
	VirtualFree(ptr, 0, MEM_RELEASE);
#elif __linux__ // linux系统
#endif
}

